package com.base.cn.platform.os.service.op.article;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.dao.op.article.OpArticleDao;
import com.base.cn.platform.os.entity.op.article.OpArticle;
import com.base.cn.platform.os.entity.op.article.OpArticleContext;
import com.base.cn.platform.os.entity.op.article.OpArticleType;
import com.base.cn.platform.os.service.op.groom.OpGroomDataBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * 资讯Biz
 * @author zsw
 * @create 2018/5/8
 */
@Service
public class OpArticleBiz extends BaseBiz<OpArticle,OpArticleDao> {

    @Autowired
    private OpArticleContextBiz opArticleContextBiz;
    @Autowired
    private OpArticleTypeBiz opArticleTypeBiz;
    @Autowired
    private OpGroomDataBiz opGroomDataBiz;

    /**
     * 查询资讯
     * @param page 当前页数
     * @param article
     * @return
     */
    public PageInfo<OpArticle> queryArticleList(Pagination page, OpArticle article, boolean setContext, boolean setType){
        String whereSql = this.getWhereSql(article);
        PageInfo<OpArticle> pageInfo = findPage(whereSql, page, null);
        List<OpArticle> articleList = pageInfo.getList();
        this.setArticleContext(articleList, setContext);
        this.setArticleType(articleList, setType);
        pageInfo.setList(articleList);
        return pageInfo;
    }

    /**
     * 保存资讯
     * @param article 资讯实体
     * @return
     */
    @Transactional(rollbackFor =  IllegalArgumentException.class)
    public OpArticle saveArticle(OpArticle article){
        if (DataUtil.idIsNotNull(article.getId())) {
            OpArticle database = findById(article.getId());
            database.setTypeId(article.getTypeId());
            database.setTitle(article.getTitle());
            database.setAuthor(article.getAuthor());
            database.setBriefIntroduction(article.getBriefIntroduction());
            database.setKeyWord(article.getKeyWord());
            database.setImageJson(article.getImageJson());
            database.setLink(article.getLink());
            database.setClickNum(article.getClickNum());
            if (database.getReleaseStatus() != 2) {
                database.setReleaseStatus(article.getReleaseStatus());
            }
            if (database.getStatus() != 0 && database.getStatus() != 3) {
                database.setStatus(article.getStatus());
            }else{
                database.setStatus(0);
            }
            updateById(database, null);
            database.setArticleContext(article.getArticleContext());
            article = database;
        } else {
            save(article);
        }
        OpArticleContext context = article.getArticleContext();
        context.setArticleId(article.getId());
        opArticleContextBiz.saveArticleContext(context);
        return article;
    }

    /**
     * 删除资讯
     * @param articleIds 资讯id串
     * @return
     */
    public void deleteArticle(String articleIds) {
        this.deleteWhereSql(" id in ("+ articleIds +") ");
        //同时删除推荐位的数据
        opGroomDataBiz.deleteGroomDataByDataIdAndDataType(articleIds,"ARTICLE");
    }

    /**
     * 根据id查询资讯
     * @param id 资讯id
     * @return
     */
    public OpArticle findArticleById(BigDecimal id, boolean setRecommend, int count){
        OpArticle opArticle = findById(id);
        opArticle.setClickNum(opArticle.getClickNum() + 1);
        this.updateByWhereSql(opArticle," id =" + id);
        this.setArticleContext(Collections.singletonList(opArticle), true);
        // TODO 设置资讯推荐, count 条数
        List<OpArticle> recommendList = this.setRecommend(opArticle, setRecommend, count);
        opArticle.setRecommendList(recommendList);
        return opArticle;
    }

    /**
     * 设置资讯推荐
     * @param article
     * @param setRecommend
     * @param count
     * @return
     */
    private List<OpArticle> setRecommend(OpArticle article, boolean setRecommend, int count) {
        if (setRecommend){
            OpArticle condition = new OpArticle();
            condition.setTypeId(article.getTypeId());
            condition.setStatus(0);
            condition.setReleaseStatus(2);
            String where = this.getWhereSql(condition);
            where +=" and id != " + article.getId() + " order by id desc";
            return find(where, count, null);
        }
        return null;
    }

    /**
     * 设置资讯内容
     * @param articleList 资讯list
     * @param setContext 是否设置资讯内容
     */
    private void setArticleContext(List<OpArticle> articleList, boolean setContext) {
        if (setContext && ObjectUtils.isNotEmpty(articleList)) {
            String ids = DataUtil.joining(articleList, OpArticle::getId);
            Map<BigDecimal, OpArticleContext> articleContextMap = opArticleContextBiz.findArticleContextByArticleIds(ids);
            for (OpArticle article : articleList) {
                article.setArticleContext(articleContextMap.get(article.getId()));
            }
        }

    }

    /**
     * 设置资讯类型
     * @param articleList 资讯list
     * @param setType 是否设置资讯类型
     */
    private void setArticleType(List<OpArticle> articleList, boolean setType) {
        if (setType && ObjectUtils.isNotEmpty(articleList)) {
            String typeIds = DataUtil.joining(articleList, OpArticle::getTypeId);
            Map<BigDecimal, OpArticleType> articleTypeMap = opArticleTypeBiz.findArticleTypeByIds(typeIds);
            for (OpArticle article : articleList) {
                article.setOpArticleType(articleTypeMap.get(article.getTypeId()));
            }
        }
    }

    /**
     * 修改资讯状态
     * @param articleIds 资讯id串
     * @param status 状态：0.正常 1.禁用 2.删除
     * @return
     */
    public void updateArticleStatusByIds(String articleIds, Integer status){
        if(StringUtils.isNotEmpty(articleIds) && StringUtils.isNotEmpty(articleIds.trim()) && ObjectUtils.isNotEmpty(status)){
            if (status == 2){
                this.deleteArticle(articleIds);
            } else {
                OpArticle opArticle = new OpArticle();
                opArticle.setStatus(status);
                this.updateByWhereSql(opArticle, " id in ("+ articleIds +")");
            }
            if(status.intValue() ==1 || status.intValue() ==2){
                //同时删除推荐位的数据
                opGroomDataBiz.deleteGroomDataByDataIdAndDataType(articleIds,"ARTICLE");
            }
        }
    }

    /**
     * 批量发布资讯
     * @param articleIds 资讯id串
     * @return
     */
    public Map<String,Object> batchPublishArticle(String articleIds){
        OpArticle article = new OpArticle();
        article.setReleaseStatus(2);
        this.updateByWhereSql(article," id in(" + articleIds + ")");
        return ResultUtil.SUCCESS("发布成功");
    }

    /**
     * 获取状态值不同的ID串
     * @param articleIds
     * @return
     */
    public String getStatusConflictIds(String articleIds){
        articleIds =StringUtils.subHeadTailString(articleIds,",");
        List<OpArticle> opArticleList = this.find(" id in("+articleIds+")",null,null);
        StringBuffer stringBuffer = new StringBuffer();
        opArticleList.forEach(v -> {
            if(v.getReleaseStatus() == 1){
                stringBuffer.append(v.getId()).append(",");
            }
        });
        return StringUtils.subHeadTailString(stringBuffer.toString(),",");
    }

    /**
     * sql模板
     * @param article 查询条件
     * @return
     */
    private String getWhereSql(OpArticle article) {
        StringBuilder whereSql = new StringBuilder("  1=1 ");
        if (DataUtil.idIsNotNull(article.getId())){
            whereSql .append( " and id in (" ).append( article.getId() ).append( ")");
        }
        if (StringUtils.isNotEmpty(article.getArticleContext())){
            whereSql .append( " and articleContext like concat('%','" ).append( article.getArticleContext() ).append( "','%')");
        }
        if (StringUtils.isNotEmpty(article.getAuthor())){
            whereSql .append( " and author =").append(article.getAuthor());
        }
        if (DataUtil.idIsNotNull(article.getTypeId())){
            whereSql .append( " and typeId =").append(article.getTypeId());
        }
        if (StringUtils.isNotEmpty(article.getReleaseStatus())){
            whereSql .append( " and releaseStatus =").append(article.getReleaseStatus());
        }
        if (StringUtils.isNotEmpty(article.getKeyWord())){
            whereSql .append( " and keyWord like concat ('%','").append( article.getKeyWord() ).append("','%')");
        }
        if (StringUtils.isNotEmpty(article.getBriefIntroduction())){
            whereSql .append( " and briefIntroduction like concat ('%','" ).append( article.getBriefIntroduction()).append("','%')");
        }
        if (StringUtils.isNotEmpty(article.getArticleContext())){
            whereSql .append( " and articleContext like concat ('%','" ).append( article.getArticleContext() ).append("','%')");
        }
        if (StringUtils.isNotEmpty(article.getTitle())){
            whereSql .append( " and title like concat ('%','" ).append( article.getTitle()).append("','%')");
        }
        if (StringUtils.isNotEmpty(article.getStatus())){
            whereSql .append( " and status = " ).append( article.getStatus());
        }
        if (StringUtils.isNotEmpty(article.getArticleNames())) {
            String[] array = StringUtils.subHeadTailString(article.getArticleNames(), ",").split(",");
            StringJoiner titleJoiner = new StringJoiner(" or ");
            for (String n : array) {
                titleJoiner.add(" ( title like '%" + n + "%' )");
            }
            whereSql.append(" and (").append(titleJoiner).append(")");
        }
        if (ObjectUtils.isNotEmpty(article.getOrder())){
            //目前资讯模块中按照时间和点击量排序的功能没有完全体现,等功能完善之后删除此提示信息
            if (article.getOrder() == 1){
                whereSql .append( " order by createTime asc");
            }
            if (article.getOrder() == 2){
                whereSql .append( " order by createTime desc ");
            }
            if (article.getOrder() == 3){
                whereSql .append( " order by clickNum asc");
            }
            if (article.getOrder() == 4){
                whereSql .append( " order by clickNum desc");
            }
        }
        return whereSql.toString();
    }

    /**
     * 根据Ids搜索资讯
     * @param articleIds 资讯id串
     * @return
     */
    public List<OpArticle> opArticlesByIds(String articleIds,Integer status,boolean setContext,boolean setType){
        StringBuilder whereSql = new StringBuilder();
        if (status>0){
            whereSql .append( " status =").append(status);
        }
        if (StringUtils.isNotEmpty(whereSql)){
            whereSql .append( " and id in (").append(articleIds).append(")");
        }else {
            whereSql .append( " id in (").append(articleIds).append(")");
        }
        List<OpArticle> opArticles = this.find(whereSql.toString(),null,null);
        opArticles =setContextAndType(opArticles,setContext,setType);
        return opArticles;
    }


    /**
     * 根据Ids搜索资讯
     * @param articleIds 资讯id串
     * @return
     */
    public Map<BigDecimal,OpArticle> opArticleMapByIds(String articleIds,Integer status,boolean setContext,boolean setType){
        List<OpArticle> opArticles = this.opArticlesByIds(articleIds,status,setContext,setType);
        return opArticles.stream().collect(Collectors.toMap(OpArticle::getId,e->e));
    }

    /**
     * set内容和类型
     * @param opArticles 资讯list
     * @param setContext 是否设置资讯内容
     * @param setType 是否设置资讯类型
     * @return
     */
    public List<OpArticle> setContextAndType(List<OpArticle> opArticles,boolean setContext,boolean setType){
        if(ObjectUtils.isNotEmpty(opArticles)){
            if (setContext){
                setArticleContext(opArticles,setContext);
            }
            if (setType){
                setArticleType(opArticles,setType);
            }
        }
        return opArticles;
    }

    public List<OpArticle> findOpArticleList(OpArticle opArticle) {
        String whereSql = getWhereSql(opArticle);
        List<OpArticle> opArticleList = this.find(whereSql, null, null);
        return opArticleList;
    }

    /**
     * 根据资讯类型id串修改资讯状态
     *
     * @param articleTypeIds  资讯类型id串
     * @param status 修改的状态
     */
    public void updateArticleStatusByArticleTypeIds(String articleTypeIds,Integer status){
        List<OpArticle> articleList = this.find(" typeId in (" + articleTypeIds+")",null,null);
        String articleIds = articleList.stream().filter(e -> StringUtils.isNotEmpty(e.getId())).map(e -> e.getId().toString()).collect(Collectors.joining(","));
        OpArticle opArticle = new OpArticle();
        opArticle.setStatus(status);
        this.updateByWhereSql(opArticle," id in ("+articleIds+")");
        if (status == 3){
            //同时删除推荐位的数据
            opGroomDataBiz.deleteGroomDataByDataIdAndDataType(articleIds,"ARTICLE");
        }
    }
}
